﻿#include "PhysicsDialogGeneralLaminate.h"
#include "ui_PhysicsDialogGeneralLaminate.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKPhyscisPropertyGeneralLaminate.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKAcousticsAbsMaterial.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKAcousticsPhysics.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKAcousticsSpectraManager.h"
#include <QMessageBox>
#include <QComboBox>
namespace GUI
{
    PhysicsDialogGeneralLaminate::PhysicsDialogGeneralLaminate(PhysicsDlgExecType type, int propid/*=-1*/, QWidget* parent /*= nullptr*/)
        :AbstractMaterialDialog(type, parent)
    {
        _ui = new Ui::PhysicsDialogGeneralLaminate;
        _ui->setupUi(this);
        //获取对象
        if (_propMgr && _matMgr && propid > 0)
            _prop = dynamic_cast<Acoustics::FITKPhyscisPropertyGeneralLaminate*>(_propMgr->getDataByID(propid));

        this->init();

    }

    PhysicsDialogGeneralLaminate::~PhysicsDialogGeneralLaminate()
    {
        if (_ui) delete _ui;
    }

    void PhysicsDialogGeneralLaminate::on_pushButton_OK_clicked()
    {
        if (!this->checkInput()) return;
        //要处理的对象
        Acoustics::FITKPhyscisPropertyGeneralLaminate* general = dynamic_cast<Acoustics::FITKPhyscisPropertyGeneralLaminate*>(_prop);
        
        QStringList str{};
        QString name = _ui->lineEdit_name->text();
        //创建与复制,创建新对象
        if (_execType == GUI::PhysicsDlgExecType::Create || _execType == GUI::PhysicsDlgExecType::Duplicate)
        {
            str.append("p=PhyscisProp.GeneralLaminate()");
            str.append(QString("p.createPhyscisProp('%1')").arg(name));
            general = new Acoustics::FITKPhyscisPropertyGeneralLaminate;
            _propMgr->appendDataObj(general);
        }
        if (!general)return;

        //保存数据    
        if (_execType == GUI::PhysicsDlgExecType::Edit) {
            str.append(QString("p=PhyscisProp.GeneralLaminate.GetGeneralLaminate('%1')").arg(general->getDataObjectName()));
            str.append(QString("p.setName('%1')").arg(name));
            for (int i = 1; i < general->getDataCount() + 1; ++i)
                str.append(QString("p.deleteLayer(%1)").arg(i));
        }
        general->clear();
        general->setDataObjectName(name);
        for (int i = 0; i < _ui->tableWidget->rowCount(); i++)
        {
            Acoustics::FITKPhyscisPropertyGeneralLaminateIsoLayer * isoLayer 
                = new Acoustics::FITKPhyscisPropertyGeneralLaminateIsoLayer;
            QComboBox* materialCombobox = static_cast<QComboBox*>(_ui->tableWidget->cellWidget(i, 1));
            QString matName{};
            if (materialCombobox)
            {
                matName = materialCombobox->currentText();
                isoLayer->setMaterialID(materialCombobox->currentData().toInt());
            }
            double thickness = _ui->tableWidget->item(i, 2)->text().toDouble();
            double angle = _ui->tableWidget->item(i, 3)->text().toDouble();

            isoLayer->setThickness(thickness);
            isoLayer->setAngle(angle);
            QComboBox* spectraCombobox = static_cast<QComboBox*>(_ui->tableWidget->cellWidget(i, 4));
            QString spectraName{};
            if (spectraCombobox)
            {
                spectraName= spectraCombobox->currentText();
                isoLayer->setDLFSplectrumID(spectraCombobox->currentData().toInt());
            }
            str.append(QString("p.addLayer('%1',%2,%3,'%4')").arg(matName).arg(thickness).arg(angle).arg(spectraName));
            general->insertDataObj(i, isoLayer);
        }
        this->saveScript(str);
        this->accept();
    }

    void PhysicsDialogGeneralLaminate::on_pushButton_Cancel_clicked()
    {
        this->reject();
    }

    void PhysicsDialogGeneralLaminate::on_pushButton_insert_clicked()
    {
        QList<QTableWidgetSelectionRange> selectedRanges = _ui->tableWidget->selectedRanges();
        if (selectedRanges.isEmpty())return;

        int rowToInsertAbove = selectedRanges.first().topRow();
        _ui->tableWidget->insertRow(rowToInsertAbove);
        _ui->tableWidget->setItem(rowToInsertAbove, 0, new QTableWidgetItem(QString::number(rowToInsertAbove+1)));
        //添加材料选项
        QComboBox* comboBox = new QComboBox;
        initializeMaterialComboBox(comboBox);
        connect(comboBox, SIGNAL(currentIndexChanged(QString)), this, SLOT(slot_comboBox_currentText(QString)));
        _ui->tableWidget->setCellWidget(rowToInsertAbove, 1, comboBox);
        ///添加厚度角度
        _ui->tableWidget->setItem(rowToInsertAbove, 2, new QTableWidgetItem("0"));
        _ui->tableWidget->setItem(rowToInsertAbove, 3, new QTableWidgetItem("0"));
        //添加频率选项
        QComboBox* comboboxDomain = new QComboBox;
        initializeSpectraComboBox(comboboxDomain);
        _ui->tableWidget->setCellWidget(rowToInsertAbove, 4, comboboxDomain);

        int rows = _ui->tableWidget->rowCount();
        for (int i = 0; i < rows; i++)
        {
            _ui->tableWidget->setItem(i, 0, new QTableWidgetItem(QString::number(i + 1)));
        }
    }

    void PhysicsDialogGeneralLaminate::on_pushButton_add_clicked()
    {
        int row = _ui->tableWidget->rowCount();
        _ui->tableWidget->insertRow(row);
        _ui->tableWidget->setItem(row, 0, new QTableWidgetItem(QString::number(row+1)));
        //添加材料选项
        QComboBox* comboBox = new QComboBox;
        initializeMaterialComboBox(comboBox);
        connect(comboBox, SIGNAL(currentIndexChanged(QString)), this, SLOT(slot_comboBox_currentText(QString)));
        _ui->tableWidget->setCellWidget(row , 1, comboBox);
        ///添加厚度角度
        _ui->tableWidget->setItem(row , 2, new QTableWidgetItem("0"));
        _ui->tableWidget->setItem(row , 3, new QTableWidgetItem("0"));
        //添加频率选项
        QComboBox* comboboxDomain = new QComboBox;
        initializeSpectraComboBox(comboboxDomain);
        _ui->tableWidget->setCellWidget(row , 4, comboboxDomain);

    }

    void PhysicsDialogGeneralLaminate::on_pushButton_delete_clicked()
    {
        QList<QTableWidgetSelectionRange> selectedRanges = _ui->tableWidget->selectedRanges();
        if (selectedRanges.isEmpty())return;
        // 删除所选范围内的行
        for (const auto &range : selectedRanges)
        {
            for (int row = range.bottomRow(); row >= range.topRow(); --row)
            {
                _ui->tableWidget->removeRow(row);
            }
        }

        int rows = _ui->tableWidget->rowCount();
        for (int i = 0; i < rows; i++)
        {
            _ui->tableWidget->setItem(i, 0, new QTableWidgetItem(QString::number(i + 1)));
        }
    }

    void PhysicsDialogGeneralLaminate::slot_comboBox_currentText(QString str)
    {
        if (!_matMgr) return;
        Interface::FITKAbstractMaterial* material = _matMgr->getDataByName(str);
        Acoustics::FITKAcousticsAbsMaterial* materialPtr = dynamic_cast<Acoustics::FITKAcousticsAbsMaterial*>(material);
        if (!materialPtr)return;

        //获取当前行的item
        int curRow = _ui->tableWidget->currentRow();
        QWidget* widget = _ui->tableWidget->cellWidget(curRow, 4);
        QComboBox* comboBox = dynamic_cast<QComboBox*>(widget);
        if (nullptr == comboBox)return;

        if (materialPtr->getAcousticsMaterialType() == Acoustics::FITKAcousticsAbsMaterial::ViscoElastic)
        {
            //如果是粘弹性材料，阻尼损耗因子不可选
            comboBox->setEnabled(false);
        }else{
            comboBox->setEnabled(true);
        }
    }
    void PhysicsDialogGeneralLaminate::init()
    {
        if (_propMgr == nullptr|| _matMgr==nullptr) return;
        if (_execType == GUI::PhysicsDlgExecType::Create)
        {
            QString name = _propMgr->checkName("New Physics Property Uniform");
            _ui->lineEdit_name->setText(name);
        }
        if (_prop == nullptr) return;
        Acoustics::FITKPhyscisPropertyGeneralLaminate* general = dynamic_cast<Acoustics::FITKPhyscisPropertyGeneralLaminate*>(_prop);
        if (!general) return;

        
    // 设置各个属性的值
        int row = general->getLayerCount();
        _ui->tableWidget->setRowCount(row);
        _ui->lineEdit_name->setText(general->getDataObjectName());
        // 隐藏行头
        _ui->tableWidget->verticalHeader()->setVisible(false);
        for (int i = 0; i < row; i++)
        {
            Acoustics::FITKPhyscisPropertyGeneralLaminateIsoLayer* isoLayer = general->getDataByIndex(i);
            if (!isoLayer) continue;
            _ui->tableWidget->setItem(i, 0, new QTableWidgetItem(QString::number(i + 1)));
        //设置频谱
            QComboBox* comboboxDomain = new QComboBox;
            initializeSpectraComboBox(comboboxDomain);
            QString text;
            Acoustics::FITKAcousticsAbstractSpectra* spec = isoLayer->getDLFSplectrumObj();
            if (spec) text = spec->getDataObjectName();
            if (text.isEmpty())
                comboboxDomain->setCurrentIndex(-1);
            else
                comboboxDomain->setCurrentText(text);
            _ui->tableWidget->setCellWidget(i, 4, comboboxDomain);
        //设置材料
            QComboBox* comboBox = new QComboBox;
            initializeMaterialComboBox(comboBox);       
            int id1 = isoLayer->getMaterialID();
            int index1 = comboBox->findData(id1);
            comboBox->setCurrentIndex(index1);
            Interface::FITKAbstractMaterial* material = _matMgr->getDataByID(id1);
            Acoustics::FITKAcousticsAbsMaterial* materialPtr = dynamic_cast<Acoustics::FITKAcousticsAbsMaterial*>(material);
            if (materialPtr) {
                if (materialPtr->getAcousticsMaterialType() == Acoustics::FITKAcousticsAbsMaterial::ViscoElastic)
                    //如果是粘弹性材料，阻尼损耗因子不可选
                    comboboxDomain->setEnabled(false);
                else 
                    comboboxDomain->setEnabled(true);
            }
            connect(comboBox, SIGNAL(currentIndexChanged(QString)), this, SLOT(slot_comboBox_currentText(QString)));
            _ui->tableWidget->setCellWidget(i, 1, comboBox);
        //设置厚度和角度
            _ui->tableWidget->setItem(i, 2, new QTableWidgetItem(QString::number(isoLayer->getThickness())));
            _ui->tableWidget->setItem(i, 3, new QTableWidgetItem(QString::number(isoLayer->getAngle())));
        
        }
        //复制,更新名称
        if (_execType == GUI::PhysicsDlgExecType::Duplicate)
        {
            QString text = QString("Copy of %1").arg(general->getDataObjectName());
            _ui->lineEdit_name->setText(text);
        }
        _ui->tableWidget->resizeColumnsToContents();
    }

    bool PhysicsDialogGeneralLaminate::checkInput()
    {
        if (_propMgr == nullptr) return false;
        //检查名称
        QString text = _ui->lineEdit_name->text().trimmed();
        if (text != "") {
            QString newText = _propMgr->checkName(text);
            if (text == newText) return true;
            //与自己重名
            if (_propMgr->getDataByName(text) == _prop) return true;
        }
        QMessageBox::critical(nullptr, tr("Critical"), tr("Please enter a new Name."));
        return false;
    }

    void PhysicsDialogGeneralLaminate::initializeMaterialComboBox(QComboBox * comboBox)
    {
        if (!_matMgr)return;
        QList<Acoustics::FITKAcousticsAbsMaterial*> list=_matMgr->
            getAcousticsMaterials(Acoustics::FITKAcousticsAbsMaterial::AcousticsMaterialType::ISOSolid);
        list+=_matMgr->
            getAcousticsMaterials(Acoustics::FITKAcousticsAbsMaterial::AcousticsMaterialType::ViscoElastic);
        for (int i = 0; i < list.size(); i++)
        {
            Acoustics::FITKAcousticsAbsMaterial* materialPtr = dynamic_cast<Acoustics::FITKAcousticsAbsMaterial*>(list[i]);
            if (!materialPtr)continue;
            comboBox->addItem(materialPtr->getDataObjectName(), materialPtr->getDataObjectID());
        }
    }

    void PhysicsDialogGeneralLaminate::initializeSpectraComboBox(QComboBox * comboBox)
    {
        Acoustics::FITKAcousticsPhysics* phy = Acoustics::FITKAcousticsPhysics::GetAcousticsPhysicsFromFrame();
        if (phy == nullptr) return;
        Acoustics::FITKAcousticsSpectraManager* spmgr = phy->getFITKAcousticsSpectraManager();
        if (spmgr == nullptr) return;
        for (int i = 0; i < spmgr->getDataCount(); i++)
        {
            auto specPtr = spmgr->getDataByIndex(i);
            if (!specPtr)continue;
            comboBox->addItem(specPtr->getDataObjectName(), specPtr->getDataObjectID());
        }
    }
}